import java.net.*;
import java.io.*;
import java.util.*;

public class EchoServer implements Runnable
{
	protected static PrintWriter outLog = null;
	protected static PrintWriter outp = null;
	protected static Vector threadTable = null;
	protected String whichThread;
	public EchoServer(String whichThread)
	{
		this.whichThread = whichThread;
	}
	public void consoleThread()
	{
		BufferedReader brInput = null;
		String line;
		try{
		outp = new PrintWriter(new OutputStreamWriter(System.out, "Cp852"), true);
		}
		catch(UnsupportedEncodingException e){
			System.out.println("Nie mona ustawi strony kodowej Cp852.");
			outp = new PrintWriter(new OutputStreamWriter(System.out), true);
		}
		try{
			outLog = new PrintWriter (new FileOutputStream("ServerLog.txt"), true);
		}
		catch(FileNotFoundException e){
			outp.println("Nie moge utworzy pliku logu.");
			System.exit(-1);
		}
		try{
			brInput = new BufferedReader(new InputStreamReader(System.in));
		}
		catch(Exception e){
			outp.println("Bd przy tworzeniu strumienia wejciowego: " + e);
			System.exit(-1);
		}
		while(true){
			try{
				line = brInput.readLine();
				if (line.equals("quit")){
					writeLog("Koczenie pracy...");
					System.exit(0);
				}
				else if (line.equals("status")){
					showStatus();
				}
				else if (line.equals("help")){
					showHelp();
				}
				else{
					outp.println("Nieznane polecenie");
				}
			}
			catch(IOException e){
				writeLog("Bd wejcia-wyjcia: " + e);
				System.exit(-1);
			}
			catch(Exception e){
				writeLog("Bd oglny: " + e);
				System.exit(-1);
			}
		}
	}
	public void networkThread()
	{
		ServerSocket serverSocket = null;
		Socket socket = null;
		InputStream inp = null;
		BufferedReader brinp = null;
		DataOutputStream out = null;
		threadTable = new Vector();
		try{
			serverSocket = new ServerSocket(6666);
		}
		catch(IOException e){
			writeLog("Bd przy tworzeniu gniazda serwerowego.");
			System.exit(-1);
		}
		writeLog("Inicjalizacja gniazda zakoczona...");
		writeLog("Parametry gniazda: " + serverSocket);
		while(true){
			try{
				socket = serverSocket.accept();
			}
			catch(IOException e){
				writeLog("Bd wejcia-wyjcia: " + e);
			}
			writeLog("Nadeszo poczenie...");
			writeLog("Parametry poczenia: " + socket);
			EchoServerThread tempThread;
			tempThread = new EchoServerThread(socket, outLog, this);
			threadTable.add(tempThread);
			tempThread.start();
		}
	}
	public void showStatus()
	{
		synchronized(threadTable){
			for (int i = 0; i < threadTable.size(); i++){
				EchoServerThread tempObj;
				tempObj = (EchoServerThread) threadTable.elementAt(i);
				outp.println(tempObj.getInfo());
			}
		}
		if (threadTable.size() < 1){
			outp.println("Nie ma adnych pocze.");
		}
	}
	public void showHelp(){
		outp.println("Rozpoznawalne polecenia to: status help quit");
	}
	public void run()
	{
		if (whichThread.equals("console")){
			consoleThread();
		}
		else if(whichThread.equals("network")){
			networkThread();
		}
		else{
			System.out.println("Wewntrzny bd programu.");
			System.exit(-1);
		}
	}
	public static void main(String args[])
	{
		EchoServer console = new EchoServer("console");
		EchoServer network = new EchoServer("network");
		new Thread(console).start();
		new Thread(network).start();
	}
	public static void writeLog(String line){
		synchronized(outLog){
			outLog.println(line);
		}
	}
	public void removeThread(Object o){
		synchronized(threadTable){
			try{
				threadTable.remove(o);
			}
			catch(Exception e){
				writeLog("Bd przy usuwaniu elementu tablicy wtkw.");
			}
		}
	}
}
